/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <string>
#include <ctime>
#include <chrono>
#include <nlohmann/json.hpp>
#include <functional>

namespace El {
namespace Record {

/**
 * @brief 路径相关的工具函数
 */
class PathUtils {
public:
    static PathUtils &GetInstance();

    /**
     * @brief 设置存储根路径
     * @param storePath 存储根路径
     */
    void SetStorePath(const std::string &storePath)
    {
        storePath_ = storePath;
    }

    /**
     * @brief 生成文件名
     * @param timestamp 时间戳
     * @param ch 通道号
     * @param type 类型号
     * @param fileType 文件类型 (如 "videos", "images", "thumbnails")
     * @param extension 文件扩展名 (如 ".mp4", ".jpg")
     * @return 完整的文件路径
     */
    std::string GenerateFilename(time_t timestamp,
                                 int32_t ch,
                                 int32_t type,
                                 const std::string &fileType,
                                 const std::string &extension);

    /**
     * @brief 生成索引文件路径
     * @param timestamp 时间戳
     * @return 索引文件路径
     */
    std::string GenerateIndexPath(time_t timestamp);

    /**
     * @brief 生成缩略图路径
     * @param imagePath 原始图片路径
     * @return 缩略图路径
     */
    std::string GenerateThumbnailPath(const std::string &imagePath);

    /**
     * @brief 根据日期获取目录路径 (YYYY/MM/DD)
     * @param date 日期(YYYYMMDD格式)
     * @return 目录路径
     */
    std::string GetDateDirPath(const std::string &date);

    /**
     * @brief 根据日期获取索引文件路径
     * @param date 日期(YYYYMMDD格式)
     * @return 索引文件路径
     */
    std::string GetIndexFilePath(const std::string &date);

    /**
     * @brief 根据日期和文件名获取视频文件路径
     * @param date 日期(YYYYMMDD格式)
     * @param filename 文件名
     * @return 视频文件路径
     */
    std::string GetVideoFilePath(const std::string &date, const std::string &filename);

    /**
     * @brief 根据日期和文件名获取图片文件路径
     * @param date 日期(YYYYMMDD格式)
     * @param filename 文件名
     * @return 图片文件路径
     */
    std::string GetImageFilePath(const std::string &date, const std::string &filename);

    /**
     * @brief 获取父目录路径
     * @param path 文件或目录路径
     * @return 父目录路径
     */
    std::string GetParentPath(const std::string &path);

    /**
     * @brief 遍历存储目录
     * @param callback 处理每个日期目录的回调函数，参数为日期(YYYYMMDD格式)和目录路径
     */
    void TraverseStorageDirectory(const std::function<void(const std::string &, const std::string &)> &callback);

    /**
     * @brief 递归删除目录
     * @param path 目录路径
     */
    void RemoveDirectoryRecursively(const std::string &path);

    /**
     * @brief 检查目录是否为空
     * @param path 目录路径
     * @return true 目录为空，false 目录不为空或不存在
     */
    bool IsDirectoryEmpty(const std::string &path);

    /**
     * @brief 清理空的存储目录
     * @return true 成功清理，false 目录不为空或清理失败
     */
    bool CleanEmptyStorageDirectory();

    /**
     * @brief 加载索引文件
     * @param indexPath 索引文件的完整路径
     * @return 包含索引数据的JSON对象，如果加载失败返回空JSON
     */
    nlohmann::json LoadIndex(const std::string &indexPath);

    /**
     * @brief 写入索引文件
     * @param indexPath 索引文件的完整路径
     * @param indexJson 要写入的JSON数据
     * @return true 写入成功，false 写入失败
     */
    bool WriteIndex(const std::string &indexPath, const nlohmann::json &indexJson);

    /**
     * @brief 解析视频文件名
     * @param filename 文件名 (格式: YYYYMMDD_HHMMSS_ch_type.mp4)
     * @return 包含视频信息的JSON对象，如果解析失败返回空JSON
     */
    nlohmann::json ParseVideoFilename(const std::string &filename);

    /**
     * @brief 解析图片文件名
     * @param filename 文件名 (格式: YYYYMMDD_HHMMSS_ch_type.jpg)
     * @return 包含图片信息的JSON对象，如果解析失败返回空JSON
     */
    nlohmann::json ParseImageFilename(const std::string &filename);

private:
    PathUtils() = default;
    ~PathUtils() = default;

    nlohmann::json ParseMediaFilename(const std::string &filename, const std::string &expectedExtension);

private:
    std::string storePath_{"/mnt/udisk"}; // 默认存储路径
};

} // namespace Record
} // namespace El
